package com.ruicar.afs.cloud.account.common.service.impl;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruicar.afs.cloud.account.common.dto.VoucherInfoDto;
import com.ruicar.afs.cloud.account.common.entity.VoucherEntry;
import com.ruicar.afs.cloud.account.common.entity.VoucherInfo;
import com.ruicar.afs.cloud.account.common.entity.VoucherTemplateEvents;
import com.ruicar.afs.cloud.account.common.mapper.VoucherInfoMapper;
import com.ruicar.afs.cloud.account.common.service.VoucherEntryService;
import com.ruicar.afs.cloud.account.common.service.VoucherInfoService;
import com.ruicar.afs.cloud.account.common.service.VoucherTemplateEventsService;
import com.ruicar.afs.cloud.common.modules.contract.enums.VoucherStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.text.MessageFormat;
import java.util.List;

@Service
public class VoucherInfoServiceImpl extends ServiceImpl<VoucherInfoMapper, VoucherInfo> implements VoucherInfoService {
    @Autowired
    private VoucherEntryService voucherEntryService;
    @Autowired
    private VoucherTemplateEventsService voucherTemplateEventsService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public VoucherInfo saveOrUpdateVoucherInfo(VoucherInfo voucherInfo) {
        this.check(voucherInfo);
        if (voucherInfo.getId() == null) {
            voucherInfo.setStatus(VoucherStatus.NEW);
            this.save(voucherInfo);
        } else {
            VoucherInfo info = this.getById(voucherInfo.getId());
            Assert.isTrue(info != null, "数据不存在!");
            Assert.isTrue(!VoucherStatus.ACTIVE.equals(info.getStatus()), "产品信息模板信息状态生效，不可修改!");
            this.updateById(voucherInfo);
        }
        return voucherInfo;
    }

    // 获取凭证信息
    public VoucherInfoDto getVoucherInfo(Long id) {
        VoucherInfoDto dto = new VoucherInfoDto();
        VoucherInfo info = this.getById(id);
        dto.setVoucherInfo(info);
        dto.setEntryList(voucherEntryService.list(id));
        return dto;
    }

    private void check(VoucherInfo voucherInfo) {
        long count = this.baseMapper.selectCount(Wrappers.<VoucherInfo>lambdaQuery().eq(VoucherInfo::getChildBusinessCode, voucherInfo.getChildBusinessCode())
                .eq(VoucherInfo::getMainBusinessCode, voucherInfo.getMainBusinessCode()).ne(voucherInfo.getId() != null, VoucherInfo::getId, voucherInfo.getId()));
        Assert.isTrue(count < 1, "事件已存在!");
    }

    //删除产品信息模板信息
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean delVoucherInfo(Long id) {
        VoucherInfo info = this.getById(id);
        Assert.isTrue(!VoucherStatus.ACTIVE.equals(info.getStatus()), "产品信息模板信息状态生效，不可删除!");
        //删除凭证分录信息
        voucherEntryService.list(id).forEach(voucherEntry -> {
                    voucherEntryService.deleteById(voucherEntry.getId());
                }
        );
        //删除凭证主表信息
        this.removeById(id);
        return Boolean.TRUE;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean active(Long id) {
        VoucherInfo info = this.getById(id);
        Assert.isTrue(info != null, "数据不存在!");
        if (VoucherStatus.ACTIVE.equals(info.getStatus())) {
            return Boolean.TRUE;
        }
        List<VoucherEntry> list = voucherEntryService.list(Wrappers.<VoucherEntry>query().lambda().eq(VoucherEntry::getCorrelationId, id));
        Assert.isTrue(list.size() > 1 && list != null, "凭证分录数量小于两条，不可设置为生效！");
        for (VoucherEntry voucherEntry : list) {
            Assert.isTrue(StringUtils.isNotBlank(voucherEntry.getAmountExpression()),
                    MessageFormat.format("凭证分录序号：{0},科目代码：{1}的金额表达式为空，凭证模板信息不可生效!", voucherEntry.getOrderNum(), voucherEntry.getSubjectCode()));
        }
        info.setStatus(VoucherStatus.ACTIVE);
        this.updateById(info);
        return Boolean.TRUE;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean invalidity(Long id) {
        VoucherInfo info = this.getById(id);
        Assert.isTrue(info != null, "数据不存在!");
        if (VoucherStatus.INVALIDITY.equals(info.getStatus())) {
            return Boolean.TRUE;
        }
        long count = voucherTemplateEventsService.count(Wrappers.<VoucherTemplateEvents>lambdaQuery()
                .eq(VoucherTemplateEvents::getMainBusinessCode, info.getMainBusinessCode())
                .eq(VoucherTemplateEvents::getChildBusinessCode, info.getChildBusinessCode())
                .eq(VoucherTemplateEvents::getStatus, VoucherStatus.ACTIVE));
        Assert.isTrue(count < 1, "凭证事件中，主事件代码：[" + info.getMainBusinessCode() + "],子事件代码：[" + info.getChildBusinessCode() + "]已存在，不可设置无效！");
        info.setStatus(VoucherStatus.INVALIDITY);
        this.updateById(info);
        return Boolean.TRUE;
    }

    @Override
    public List<VoucherInfo> listVoucher() {
        return this.list(Wrappers.<VoucherInfo>query().lambda().eq(VoucherInfo::getStatus, VoucherStatus.ACTIVE).orderByDesc(VoucherInfo::getMainBusinessCode));
    }

}
